﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Storage;
using Oracle.EntityFrameworkCore.Infrastructure.Internal;
using Oracle.EntityFrameworkCore.Migrations;

namespace WMS.FC.Infrastructure.Common
{
    public class OracleMigrationsSqlGeneratorFix : OracleMigrationsSqlGenerator
    {

#pragma warning disable EF1001 // Internal EF Core API usage.
        public OracleMigrationsSqlGeneratorFix(MigrationsSqlGeneratorDependencies dependencies, IOracleOptions options) : base(dependencies, options)
#pragma warning restore EF1001 // Internal EF Core API usage.
        {
        }

        protected override void Generate(AddColumnOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate)
        {
            base.Generate(operation, model, builder, terminate);
            if (operation.Comment != null)
            {
                builder.Append("COMMENT ON COLUMN ").Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema)).Append(".")
                    .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name))
                    .Append(" is ")
                    .Append($"'{operation.Comment}'")
                    .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
                builder.EndCommand();
            }
        }

        protected override void Generate(AlterColumnOperation operation, IModel? model, MigrationCommandListBuilder builder)
        {
            base.Generate(operation, model, builder);
            if (operation.OldColumn.Comment != operation.Comment)
            {
                var column = model?.GetRelationalModel().FindTable(operation.Table, operation.Schema)?.Columns.FirstOrDefault((IColumn c) => c.Name == operation.Name);
                if (column != null)
                {
                    var mapping = Dependencies.TypeMappingSource.GetMapping(typeof(string));
                    builder.Append("COMMENT ON COLUMN ").Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema)).Append(".")
                        .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(column.Name))
                        .Append(" is ");
                    if (operation.Comment != null)
                    {
                        builder.Append($"'{column.Comment}'");
                    }
                    else
                    {
                        builder.Append("''");
                    }

                    builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
                    builder.EndCommand();
                }
            }
        }

        protected override void Generate(CreateTableOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate)
        {
            base.Generate(operation, model, builder, terminate);
            if (operation.Comment != null)
            {
                var mapping = Dependencies.TypeMappingSource.GetMapping(typeof(string));
                builder.Append("COMMENT ON TABLE ").Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name, operation.Schema)).Append(" is ")
                    .Append($"'{operation.Comment}'")
                    .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
                EndStatement(builder);
            }

            foreach (var item in operation.Columns.Where((AddColumnOperation c) => c.Comment != null))
            {
                var mapping2 = Dependencies.TypeMappingSource.GetMapping(typeof(string));
                builder.Append("COMMENT ON COLUMN ").Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name, operation.Schema)).Append(".")
                    .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(item.Name))
                    .Append(" is ")
                    .Append($"'{item.Comment}'")
                    .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
                EndStatement(builder);
            }
        }
    }
}
